<template>
  <div class="admin-logs">
    <div class="page-header">
      <h2>系统日志</h2>
      <div class="header-actions">
        <button class="admin-btn" @click="refreshLogs">刷新</button>
        <button class="admin-btn" @click="exportLogs">导出日志</button>
      </div>
    </div>
    
    <div class="filter-toolbar">
      <div class="search-box">
        <input 
          type="text" 
          v-model="filters.keyword" 
          class="admin-form-input" 
          placeholder="搜索日志内容"
          @input="onFilterChange"
        >
      </div>
      
      <div class="filter-options">
        <div class="filter-item">
          <select 
            v-model="filters.level" 
            class="admin-form-input"
            @change="onFilterChange"
          >
            <option value="">所有级别</option>
            <option value="info">信息</option>
            <option value="warning">警告</option>
            <option value="error">错误</option>
            <option value="critical">严重</option>
          </select>
        </div>
        
        <div class="filter-item">
          <select 
            v-model="filters.module" 
            class="admin-form-input"
            @change="onFilterChange"
          >
            <option value="">所有模块</option>
            <option value="user">用户模块</option>
            <option value="challenge">挑战模块</option>
            <option value="task">任务模块</option>
            <option value="auth">认证模块</option>
            <option value="system">系统模块</option>
          </select>
        </div>
        
        <div class="filter-item date-range-filter">
          <input 
            type="date" 
            v-model="filters.startDate" 
            class="admin-form-input date-input"
            @change="onFilterChange"
          >
          <span class="date-separator">至</span>
          <input 
            type="date" 
            v-model="filters.endDate" 
            class="admin-form-input date-input"
            @change="onFilterChange"
          >
        </div>
        
        <button class="admin-btn" @click="resetFilters">重置筛选</button>
      </div>
    </div>
    
    <div class="loading-container" v-if="loading">
      <div class="loading-spinner"></div>
      <p>加载日志中...</p>
    </div>
    
    <div class="logs-container" v-else>
      <table class="logs-table">
        <thead>
          <tr>
            <th>ID</th>
            <th>时间</th>
            <th>级别</th>
            <th>模块</th>
            <th>操作用户</th>
            <th>IP地址</th>
            <th>操作</th>
            <th>内容</th>
            <th>操作</th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="log in filteredLogs" :key="log.id" :class="'log-level-' + log.level">
            <td class="log-id">{{ log.id }}</td>
            <td class="log-time">{{ formatDate(log.timestamp) }}</td>
            <td class="log-level">
              <span class="log-level-tag" :class="'level-' + log.level">
                {{ getLevelText(log.level) }}
              </span>
            </td>
            <td class="log-module">{{ log.module }}</td>
            <td class="log-user">{{ log.username || '系统' }}</td>
            <td class="log-ip">{{ log.ip || '-' }}</td>
            <td class="log-action">{{ log.action }}</td>
            <td class="log-content">
              <div class="content-preview" @click="viewLogDetail(log)">
                {{ log.content.length > 50 ? log.content.substring(0, 50) + '...' : log.content }}
              </div>
            </td>
            <td class="log-operations">
              <button class="admin-btn admin-btn-text" @click="viewLogDetail(log)">查看</button>
            </td>
          </tr>
        </tbody>
      </table>
      
      <div class="empty-state" v-if="filteredLogs.length === 0">
        <div class="empty-icon">📋</div>
        <p>没有找到匹配的日志记录</p>
        <button class="admin-btn" @click="resetFilters">清除筛选条件</button>
      </div>
      
      <div class="pagination" v-if="totalPages > 1">
        <button 
          class="pagination-btn" 
          :disabled="currentPage === 1"
          @click="changePage(currentPage - 1)"
        >
          上一页
        </button>
        
        <div class="page-numbers">
          <button 
            v-for="page in displayedPages" 
            :key="page"
            class="page-number"
            :class="{ active: currentPage === page }"
            @click="changePage(page)"
          >
            {{ page }}
          </button>
        </div>
        
        <button 
          class="pagination-btn" 
          :disabled="currentPage === totalPages"
          @click="changePage(currentPage + 1)"
        >
          下一页
        </button>
      </div>
    </div>
    
    <!-- 日志详情弹窗 -->
    <div class="log-detail-modal" v-if="showLogDetail">
      <div class="modal-overlay" @click="showLogDetail = false"></div>
      <div class="modal-container">
        <div class="modal-header">
          <h3>日志详情</h3>
          <button class="close-btn" @click="showLogDetail = false">&times;</button>
        </div>
        
        <div class="modal-body">
          <div class="log-detail-item">
            <div class="detail-label">ID:</div>
            <div class="detail-value">{{ selectedLog.id }}</div>
          </div>
          
          <div class="log-detail-item">
            <div class="detail-label">时间:</div>
            <div class="detail-value">{{ formatDate(selectedLog.timestamp, true) }}</div>
          </div>
          
          <div class="log-detail-item">
            <div class="detail-label">级别:</div>
            <div class="detail-value">
              <span class="log-level-tag" :class="'level-' + selectedLog.level">
                {{ getLevelText(selectedLog.level) }}
              </span>
            </div>
          </div>
          
          <div class="log-detail-item">
            <div class="detail-label">模块:</div>
            <div class="detail-value">{{ selectedLog.module }}</div>
          </div>
          
          <div class="log-detail-item">
            <div class="detail-label">操作用户:</div>
            <div class="detail-value">{{ selectedLog.username || '系统' }}</div>
          </div>
          
          <div class="log-detail-item">
            <div class="detail-label">IP地址:</div>
            <div class="detail-value">{{ selectedLog.ip || '-' }}</div>
          </div>
          
          <div class="log-detail-item">
            <div class="detail-label">操作:</div>
            <div class="detail-value">{{ selectedLog.action }}</div>
          </div>
          
          <div class="log-detail-item content-item">
            <div class="detail-label">内容:</div>
            <div class="detail-value content-box">{{ selectedLog.content }}</div>
          </div>
          
          <div class="log-detail-item" v-if="selectedLog.details">
            <div class="detail-label">详细数据:</div>
            <div class="detail-value">
              <pre class="json-data">{{ JSON.stringify(selectedLog.details, null, 2) }}</pre>
            </div>
          </div>
        </div>
        
        <div class="modal-footer">
          <button class="admin-btn" @click="showLogDetail = false">关闭</button>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'AdminLogs',
  data() {
    // 初始化日期范围为当前日期的前7天到当前日期
    const today = new Date()
    const weekAgo = new Date()
    weekAgo.setDate(today.getDate() - 7)
    
    return {
      loading: true,
      logs: [],
      filteredLogs: [],
      filters: {
        keyword: '',
        level: '',
        module: '',
        startDate: this.formatDateForInput(weekAgo),
        endDate: this.formatDateForInput(today)
      },
      currentPage: 1,
      pageSize: 15,
      totalLogs: 0,
      showLogDetail: false,
      selectedLog: {}
    }
  },
  computed: {
    totalPages() {
      return Math.ceil(this.totalLogs / this.pageSize)
    },
    displayedPages() {
      // 显示当前页码周围的页码，最多显示5个页码
      const pages = []
      const totalDisplayed = 5
      let startPage = Math.max(1, this.currentPage - Math.floor(totalDisplayed / 2))
      let endPage = Math.min(this.totalPages, startPage + totalDisplayed - 1)
      
      if (endPage - startPage + 1 < totalDisplayed) {
        startPage = Math.max(1, endPage - totalDisplayed + 1)
      }
      
      for (let i = startPage; i <= endPage; i++) {
        pages.push(i)
      }
      
      return pages
    }
  },
  created() {
    this.fetchLogs()
  },
  methods: {
    fetchLogs() {
      this.loading = true
      
      // 模拟API请求
      setTimeout(() => {
        // 生成模拟数据
        this.logs = this.generateMockLogs(100)
        this.totalLogs = this.logs.length
        this.applyFilters()
        this.loading = false
      }, 1000)
    },
    generateMockLogs(count) {
      const logs = []
      const modules = ['用户模块', '挑战模块', '任务模块', '认证模块', '系统模块']
      const levels = ['info', 'warning', 'error', 'critical']
      const actions = [
        '登录', '注册', '修改资料', '创建挑战', '编辑任务', 
        '审核通过', '审核拒绝', '删除记录', '导出数据', '系统配置'
      ]
      const users = ['admin', 'moderator', 'system', 'user1', 'user2']
      
      const now = new Date()
      
      for (let i = 1; i <= count; i++) {
        const timestamp = new Date(now)
        timestamp.setMinutes(now.getMinutes() - i * 30) // 每条记录间隔30分钟
        
        const level = levels[Math.floor(Math.random() * levels.length)]
        const module = modules[Math.floor(Math.random() * modules.length)]
        const action = actions[Math.floor(Math.random() * actions.length)]
        const username = Math.random() > 0.2 ? users[Math.floor(Math.random() * users.length)] : null
        
        logs.push({
          id: count - i + 1,
          timestamp: timestamp.toISOString(),
          level,
          module,
          username,
          ip: username ? `192.168.${Math.floor(Math.random() * 255)}.${Math.floor(Math.random() * 255)}` : null,
          action,
          content: `${module}${action}操作：${level === 'error' || level === 'critical' ? '发生错误，' : ''}${this.generateRandomContent(action)}`,
          details: Math.random() > 0.5 ? {
            requestData: { param1: 'value1', param2: 'value2' },
            responseData: { status: level === 'error' ? 'failure' : 'success' }
          } : null
        })
      }
      
      return logs
    },
    generateRandomContent(action) {
      const contents = {
        '登录': '用户登录系统，IP地址验证通过',
        '注册': '新用户注册成功，初始信息已创建',
        '修改资料': '用户更新了个人资料信息',
        '创建挑战': '创建了新的环保挑战活动',
        '编辑任务': '修改了任务详情和完成条件',
        '审核通过': '管理员审核并通过了用户提交',
        '审核拒绝': '管理员拒绝了不符合要求的提交',
        '删除记录': '永久删除了系统中的记录',
        '导出数据': '导出了系统数据进行备份',
        '系统配置': '修改了系统配置参数'
      }
      
      return contents[action] || '执行了系统操作'
    },
    formatDate(dateString, withTime = false) {
      if (!dateString) return '-'
      
      const date = new Date(dateString)
      const year = date.getFullYear()
      const month = String(date.getMonth() + 1).padStart(2, '0')
      const day = String(date.getDate()).padStart(2, '0')
      
      if (!withTime) {
        return `${year}-${month}-${day}`
      }
      
      const hours = String(date.getHours()).padStart(2, '0')
      const minutes = String(date.getMinutes()).padStart(2, '0')
      const seconds = String(date.getSeconds()).padStart(2, '0')
      
      return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
    },
    formatDateForInput(date) {
      const year = date.getFullYear()
      const month = String(date.getMonth() + 1).padStart(2, '0')
      const day = String(date.getDate()).padStart(2, '0')
      return `${year}-${month}-${day}`
    },
    getLevelText(level) {
      const levelMap = {
        'info': '信息',
        'warning': '警告',
        'error': '错误',
        'critical': '严重'
      }
      return levelMap[level] || level
    },
    onFilterChange() {
      this.currentPage = 1
      this.applyFilters()
    },
    resetFilters() {
      const today = new Date()
      const weekAgo = new Date()
      weekAgo.setDate(today.getDate() - 7)
      
      this.filters = {
        keyword: '',
        level: '',
        module: '',
        startDate: this.formatDateForInput(weekAgo),
        endDate: this.formatDateForInput(today)
      }
      
      this.onFilterChange()
    },
    applyFilters() {
      let filtered = [...this.logs]
      
      // 关键词筛选
      if (this.filters.keyword) {
        const keyword = this.filters.keyword.toLowerCase()
        filtered = filtered.filter(log => 
          (log.content && log.content.toLowerCase().includes(keyword)) ||
          (log.action && log.action.toLowerCase().includes(keyword)) ||
          (log.username && log.username.toLowerCase().includes(keyword))
        )
      }
      
      // 级别筛选
      if (this.filters.level) {
        filtered = filtered.filter(log => log.level === this.filters.level)
      }
      
      // 模块筛选
      if (this.filters.module) {
        filtered = filtered.filter(log => log.module.includes(this.filters.module))
      }
      
      // 日期筛选
      if (this.filters.startDate) {
        const startDate = new Date(this.filters.startDate)
        startDate.setHours(0, 0, 0, 0)
        filtered = filtered.filter(log => new Date(log.timestamp) >= startDate)
      }
      
      if (this.filters.endDate) {
        const endDate = new Date(this.filters.endDate)
        endDate.setHours(23, 59, 59, 999)
        filtered = filtered.filter(log => new Date(log.timestamp) <= endDate)
      }
      
      this.totalLogs = filtered.length
      
      // 分页
      const start = (this.currentPage - 1) * this.pageSize
      const end = start + this.pageSize
      this.filteredLogs = filtered.slice(start, end)
    },
    changePage(page) {
      if (page < 1 || page > this.totalPages) return
      this.currentPage = page
      this.applyFilters()
      
      // 滚动到顶部
      window.scrollTo(0, 0)
    },
    refreshLogs() {
      this.fetchLogs()
    },
    viewLogDetail(log) {
      this.selectedLog = log
      this.showLogDetail = true
    },
    exportLogs() {
      alert('导出日志功能将生成CSV文件')
      // 实际应用中，这里会调用API导出日志
    }
  }
}
</script>

<style scoped>
.admin-logs {
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
}

.page-header h2 {
  margin: 0;
}

.header-actions {
  display: flex;
  gap: 8px;
}

.filter-toolbar {
  padding: 16px;
  background-color: white;
  border-radius: 4px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.filter-options {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  align-items: center;
}

.filter-item {
  min-width: 150px;
}

.date-range-filter {
  display: flex;
  align-items: center;
  min-width: 320px;
}

.date-input {
  width: 140px;
}

.date-separator {
  margin: 0 8px;
}

.loading-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 48px 0;
  background-color: white;
  border-radius: 4px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
}

.loading-spinner {
  width: 40px;
  height: 40px;
  border: 4px solid #f3f3f3;
  border-top: 4px solid #1890ff;
  border-radius: 50%;
  animation: spin 1s linear infinite;
  margin-bottom: 16px;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

.logs-container {
  background-color: white;
  border-radius: 4px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
  overflow: hidden;
}

.logs-table {
  width: 100%;
  border-collapse: collapse;
}

.logs-table th,
.logs-table td {
  padding: 12px 16px;
  text-align: left;
  border-bottom: 1px solid #f0f0f0;
}

.logs-table th {
  background-color: #fafafa;
  font-weight: 500;
  color: rgba(0, 0, 0, 0.85);
}

.logs-table tr:hover {
  background-color: #f5f5f5;
}

.log-id {
  width: 60px;
  color: rgba(0, 0, 0, 0.45);
}

.log-time {
  white-space: nowrap;
}

.log-level-tag {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 10px;
  font-size: 12px;
}

.level-info {
  background-color: #e6f7ff;
  color: #1890ff;
}

.level-warning {
  background-color: #fff7e6;
  color: #fa8c16;
}

.level-error {
  background-color: #fff1f0;
  color: #f5222d;
}

.level-critical {
  background-color: #f5222d;
  color: white;
}

.log-content {
  max-width: 300px;
}

.content-preview {
  cursor: pointer;
  color: #1890ff;
}

.content-preview:hover {
  text-decoration: underline;
}

.log-operations {
  white-space: nowrap;
  width: 60px;
}

.admin-btn-text {
  background: none;
  border: none;
  color: #1890ff;
  padding: 4px 8px;
}

.admin-btn-text:hover {
  background-color: rgba(24, 144, 255, 0.1);
}

.empty-state {
  padding: 48px;
  text-align: center;
  color: rgba(0, 0, 0, 0.45);
}

.empty-icon {
  font-size: 48px;
  margin-bottom: 16px;
}

.pagination {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 16px;
  border-top: 1px solid #f0f0f0;
}

.pagination-btn {
  padding: 4px 12px;
  background-color: white;
  border: 1px solid #d9d9d9;
  border-radius: 4px;
  cursor: pointer;
}

.pagination-btn:disabled {
  color: rgba(0, 0, 0, 0.25);
  cursor: not-allowed;
}

.page-numbers {
  display: flex;
  margin: 0 16px;
}

.page-number {
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 4px;
  border: 1px solid #d9d9d9;
  border-radius: 4px;
  background-color: white;
  cursor: pointer;
}

.page-number.active {
  background-color: #1890ff;
  border-color: #1890ff;
  color: white;
}

/* 日志详情弹窗 */
.log-detail-modal {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
}

.modal-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.5);
}

.modal-container {
  position: relative;
  width: 600px;
  max-width: 90%;
  max-height: 80vh;
  background-color: white;
  border-radius: 4px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.modal-header {
  padding: 16px 24px;
  border-bottom: 1px solid #f0f0f0;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.modal-header h3 {
  margin: 0;
}

.close-btn {
  background: none;
  border: none;
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  color: rgba(0, 0, 0, 0.45);
}

.modal-body {
  padding: 24px;
  overflow-y: auto;
}

.log-detail-item {
  display: flex;
  margin-bottom: 16px;
}

.log-detail-item:last-child {
  margin-bottom: 0;
}

.detail-label {
  width: 100px;
  font-weight: 500;
  color: rgba(0, 0, 0, 0.85);
}

.content-item {
  align-items: flex-start;
}

.content-box {
  background-color: #f5f5f5;
  padding: 12px;
  border-radius: 4px;
  white-space: pre-wrap;
}

.json-data {
  background-color: #f5f5f5;
  padding: 12px;
  border-radius: 4px;
  overflow-x: auto;
  font-family: monospace;
  font-size: 14px;
}

.modal-footer {
  padding: 12px 24px;
  border-top: 1px solid #f0f0f0;
  text-align: right;
}

@media (max-width: 768px) {
  .filter-options {
    flex-direction: column;
    align-items: stretch;
  }
  
  .filter-item,
  .date-range-filter {
    min-width: auto;
    width: 100%;
  }
  
  .date-range-filter {
    flex-wrap: wrap;
  }
  
  .logs-table {
    display: block;
    overflow-x: auto;
  }
  
  .detail-label {
    width: 80px;
  }
}
</style> 